/*******************************************************************************
* COPYRIGHT LIPUJUN TECH CO.,LTD
********************************************************************************
* ÃÃÅÃŸÃÃ»Â³Ã:  task.c
* Â¹Å ÃÃÃÃšÃÃ¶:
* ÃÂ¹ÃÃÃÂµÃÃ·:  ÃÃ
* ÃÃÅÃŸÃÃ·ÃÃ:  LIPUJUN
* Â±Ã ÃÅœÃÃÃÃ:  2018/11/28
* ÃÃÅŸÃÃÃºÃÂ·:
* ÃÃÅŸÃÂ°ÃŠÂ±Åž  ÃÃÅŸÃÃÃÃÃ       ÃÃÅŸÃÃÃ   ÃÃÅŸÃÃÃÃÃ
  01a       2018/11/28       ÃÃ®ÃÃÅžÃŒ   ÅœÅœÅÅ¡
*******************************************************************************/

/******************************* Â°ÃŒÂºÂ¬ÃÃÅÃŸÃÃ¹ÃÃ· ********************************/
#define _XOPEN_SOURCE 
#define _GNU_SOURCE
#include <time.h>
#include "common.h"
#include "user_core.h"
//#include "slog.h"
#include <ctype.h>
#include <stdlib.h>
#include <ifaddrs.h>
#include <linux/if.h> 
#include <arpa/inet.h>
#include <sys/ioctl.h>


//extern int logger_restart(void);
extern AIR_APP_INFO_T stMqttMsgInfo;
//extern MQTT_CLIENT_INFO_T stMqttClientInfo;
CHAR g_timeBuf [0x20];
CHAR g_timeBuf0[0x20];

void get_appVer (CHAR *ver)
{
    sprintf (ver, "%s", SF_VER);
}

INT32 get_diskSize (CHAR* disk_total)
{
    struct statfs diskInfo; 
 
    if ( -1 == statfs(DATA_STORE_BASE_PATH, &diskInfo)){
        Error("get_diskSize statfs %s %d(%s)",DATA_STORE_BASE_PATH ,errno, strerror(errno));
        return ERROR;
    }  
    UINT64 totalSize = diskInfo.f_blocks * diskInfo.f_bsize;   
    UINT32 mbTotalsize = totalSize >> 30; //GB 
    sprintf(disk_total,"%d",mbTotalsize);
    return OK;
}
INT32 get_localMAC (CHAR *mac, CHAR *name)
{
    struct ifaddrs * ifAddr = NULL;
    void * tmpAddrPtr = NULL;
    getifaddrs(&ifAddr);
 
    while (ifAddr != NULL) {      
       if (ifAddr->ifa_addr && ifAddr->ifa_addr->sa_family == AF_INET) { // check it is IP4
            // is a valid IP4 Address 
            tmpAddrPtr=&((struct sockaddr_in *)ifAddr->ifa_addr)->sin_addr;
            char addr[INET_ADDRSTRLEN] = {0};
            inet_ntop(AF_INET, tmpAddrPtr, addr, INET_ADDRSTRLEN);

            if(strcmp(addr,stMqttMsgInfo.ip) == 0){
                int skfd = 0;  
                struct ifreq ifr;     

                skfd = socket(AF_INET, SOCK_DGRAM, 0);  
                if(skfd < 0){
                    Error("get local mac socketfd error");
                    strcpy(mac,"000000000000");
                    strcpy(name,"bond0");
                    return ERROR;
                }
                strcpy(ifr.ifr_name, ifAddr->ifa_name);  
                strcpy(name, ifAddr->ifa_name);  
                if(ioctl(skfd,SIOCGIFHWADDR,&ifr) < 0){
                    Error("get local mac ioctl error");
                    close(skfd);
                    strcpy(mac,"000000000000");
                    strcpy(name,"bond0");
                    return ERROR;
                }  
                sprintf(mac,"%02x%02x%02x%02x%02x%02x", 
                       (unsigned char)ifr.ifr_hwaddr.sa_data[0],  
                       (unsigned char)ifr.ifr_hwaddr.sa_data[1],  
                       (unsigned char)ifr.ifr_hwaddr.sa_data[2],  
                       (unsigned char)ifr.ifr_hwaddr.sa_data[3],  
                       (unsigned char)ifr.ifr_hwaddr.sa_data[4],  
                       (unsigned char)ifr.ifr_hwaddr.sa_data[5]);  
                 close(skfd); 
                 return OK;                
            }            

        }
        ifAddr = ifAddr->ifa_next;
    }
    strcpy(mac,"000000000000");
    strcpy(name,"bond0");
    return ERROR;   
}

INT32 get_localIPByRemoteIP (const CHAR *dstIP,CHAR *ip,int mask)
{
    struct ifaddrs * ifAddr = NULL;
    void * tmpAddrPtr = NULL;
    UINT32 dstNetIP = 0;
    
    if(dstIP == NULL)
        return ERROR;    
    dstNetIP = ntohl(inet_addr(dstIP)) & (0xffffffff << (32-mask));    
    getifaddrs(&ifAddr);

    while (ifAddr != NULL) {      
        if (ifAddr->ifa_addr && ifAddr->ifa_addr->sa_family == AF_INET) { // check it is IP4  
            UINT32 localNetIP = 0;          
            tmpAddrPtr=&((struct sockaddr_in *)ifAddr->ifa_addr)->sin_addr;
            localNetIP = ntohl(((struct sockaddr_in *)ifAddr->ifa_addr)->sin_addr.s_addr) & (0xffffffff << (32-mask));
           
            if(dstNetIP == localNetIP){
                char addr[INET_ADDRSTRLEN] = {0};
                inet_ntop(AF_INET, tmpAddrPtr, addr, INET_ADDRSTRLEN);
                strcpy(ip,addr);
                INFO("net[%s],dstIP:%s,localIP:%s\n",ifAddr->ifa_name,dstIP,ip);
                return OK;               
            }                      
        }
        ifAddr = ifAddr->ifa_next;
    }    
    return ERROR;   
}
INT32 get_ipByEthN (const CHAR *name,CHAR *ip)
{
    struct ifaddrs * ifAddr = NULL;
    void * tmpAddrPtr = NULL;
    
    getifaddrs(&ifAddr);

    while (ifAddr != NULL) {      
        if (ifAddr->ifa_addr && ifAddr->ifa_addr->sa_family == AF_INET) { // check it is IP4
            if(strcmp(name, ifAddr->ifa_name) == 0){
                tmpAddrPtr=&((struct sockaddr_in *)ifAddr->ifa_addr)->sin_addr;
                char addr[INET_ADDRSTRLEN] = {0};
                inet_ntop(AF_INET, tmpAddrPtr, addr, INET_ADDRSTRLEN);

                if(strcmp(addr,"0.0.0.0") != 0){
                    strcpy(ip,addr);
                    return OK;
                }else
                    return ERROR;
            }             
        }
        ifAddr = ifAddr->ifa_next;
    }    
    return ERROR;   
}
INT8* currentTimeGet (void)
{
    struct tm p_tm = {0};
    time_t timep;

    memset (g_timeBuf, 0x00, sizeof (g_timeBuf));

    time(&timep);
    localtime_r(&timep ,&p_tm); /*ÃÂ¡ÂµÃÂµÂ±ÂµÃÃÂ±ÅÃ€*/

    sprintf (g_timeBuf, "%04d-%02d-%02d %02d:%02d:%02d",
             p_tm.tm_year + 1900,
             p_tm.tm_mon+ 1,
             p_tm.tm_mday,
             p_tm.tm_hour/* - tz.tz_minuteswest/60*/,
             p_tm.tm_min,
             p_tm.tm_sec);

    return (g_timeBuf);
}
INT8* currentTimeGet0 (void)
{
    struct tm p_tm = {0};
    time_t timep;

    memset (g_timeBuf0, 0x00, sizeof (g_timeBuf0));

    time(&timep);
    localtime_r(&timep ,&p_tm); /*ÃÂ¡ÂµÃÂµÂ±ÂµÃÃÂ±ÅÃ€*/

    sprintf (g_timeBuf0, "%04d%02d%02d%02d%02d%02d",
             (p_tm.tm_year + 1900)%2000,
             p_tm.tm_mon+ 1,
             p_tm.tm_mday,
             p_tm.tm_hour/* - tz.tz_minuteswest/60*/,
             p_tm.tm_min,
             p_tm.tm_sec);

    return (g_timeBuf0);
}
UINT32 currentTimeGet_int (void)
{    
    time_t timep;
    time(&timep);
    return (UINT32)timep;    
}
UINT32 strTime2Int(const char* sTime)
{
    struct tm stm; 
    long t; 

    if(sTime == NULL)
	return 0;
    strptime(sTime, "%Y-%m-%d %H:%M:%S",&stm);
 
    t = mktime(&stm);
    return (UINT32)t;
}
INT8* intTime2Str(UINT32 iTime ,INT8* sTime)
{
    struct tm p_tm = {0};
    time_t timep = (time_t)iTime;

    if(sTime == NULL)
	return NULL;
    memset(sTime,0,20);
    localtime_r(&timep,&p_tm); /*ÃÂ¡ÂµÃÂµÂ±ÂµÃÃÂ±ÅÃ€*/

    sprintf (sTime, "%04d-%02d-%02d %02d:%02d:%02d",
             p_tm.tm_year + 1900,
             p_tm.tm_mon+ 1,
             p_tm.tm_mday,
             p_tm.tm_hour/* - tz.tz_minuteswest/60*/,
             p_tm.tm_min,
             p_tm.tm_sec);

    return (sTime);
}
 
void printBootLogo (UINT32 type)
{
    CHAR ver[0x40] = {0};

    printf ("\n\n\n");
    printf ("\n%28s", "AIR FLASH System Boot");
    printf ("\n\n\tCopyright 2020-2050 HTWG Systems, Inc.");   
    get_appVer(ver);
    printf ("\n\tVer: %s\n", ver);
}

void printLogo (void)
{
    printf("\n\t[%s]: HTWG System Startup Success!\n", currentTimeGet());
    printf ("\r\n  =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "); 
    printf ("\r\n  =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "); 
    printf ("\r\n  =@@@^                                                                @@@@ "); 
    printf ("\r\n  =@@@^                         .,].  ,]]]]]]]]]]]]]]]]]]O/.           @@@@ "); 
    printf ("\r\n  =@@@^                      ./@@@@` /OO@@@@@@@@@@@OOOOOOO.            @@@@ "); 
    printf ("\r\n  =@@@^                     ,O@@@@/ ,OO@@@@@@@@@@@@OOOOOO.             @@@@ "); 
    printf ("\r\n  =@@@^                    ,O@@@@@` /@@@@@@@@@@@@@OOOO/`.              @@@@ "); 
    printf ("\r\n  =@@@^                   =OO@@@@@`....... .......                     @@@@ "); 
    printf ("\r\n  =@@@^                 .=OOO@@@@@@@@@@@@^ O@@@@OO.                    @@@@ "); 
    printf ("\r\n  =@@@^                .=OO@@@@@@@@@@@@@@.=@@@@@O^                     @@@@ "); 
    printf ("\r\n  =@@@^               ./O@@@@@@@@@@@@@@@^ O@@@@@O.                     @@@@ "); 
    printf ("\r\n  =@@@^              ./@@@@@@@@/.        =@@@@@@^                      @@@@ ");  
    printf ("\r\n  =@@@^             .@@@@@@@@@@.         O@@@@@O.                      @@@@ "); 
    printf ("\r\n  =@@@^             @@@@@@@@@@^         =O@@@@@/                       @@@@ "); 
    printf ("\r\n  =@@@^             ./@@@OOOOOOo.       ,OOO@@@@@O.                    @@@@ "); 
    printf ("\r\n  =@@@^                                                                @@@@ "); 
    printf ("\r\n  =@@@^                                                                @@@@ "); 
    printf ("\r\n  =@@@^    @@@     @@@^ @@@@@@@@@@@   ,@@@@@@@]   O@@`  ,@@@@`  ,@@@^  @@@@ "); 
    printf ("\r\n  =@@@^    @@@     @@@^ [[[[@@@[[[[ ,@@@@O[[O@@@` =@@^  /@@@@/  =@@O   @@@@ "); 
    printf ("\r\n  =@@@^    @@@     @@@^     @@@    .@@@^     ,[`. .@@@.,@@@/@@` @@@^   @@@@ "); 
    printf ("\r\n  =@@@^    @@@@@@@@@@@^     @@@    =@@@.  =@@@@@@  =@@^O@@^,@@/=@@O    @@@@ "); 
    printf ("\r\n  =@@@^    @@@     @@@^     @@@    ,@@@^  =@@@@@@  .@@@@@@. .@@O@@^    @@@@ "); 
    printf ("\r\n  =@@@^    @@@     @@@^     @@@     =@@@]   ..@@@   .@@@@^  =@@@@O     @@@@ "); 
    printf ("\r\n  =@@@^    @@@     @@@^     @@@      ..@@@@@@@@O`   =@@@O    O@@@^     @@@@ "); 
    printf ("\r\n  =@@@^                                                                @@@@ "); 
    printf ("\r\n  =@@@.]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]@@@@ "); 
    printf ("\r\n  =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "); 
    printf ("\r\n  ,[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "); 
    printf ("\r\n");
    printf ("\r\n                Copyright 2020-2050  HTGW Systems, Inc.\r\n\n\n\r");
}

void printClientInfo (void)
{
    INFO ("\n\t +++ HTWG %s INFO +++\n\n"
	    "\n     local IP : %s"
	    "\n    Disk Size : %s"
	    "\n    Server IP : %s"
	    "\n  Server port : %d"
	    "\n           id : %s"
	    "\n       oldVer : %s"
	    "\n       curVer : %s"
	    "\n       tmpVer : %s"
	    "\n       appVer : %s"
	    "\n  oldFilename : %s"
	    "\n  curFilename : %s"
	    "\n  tmpFilename : %s"
	    "\n    appConfig : %s",
	    stMqttMsgInfo.appVer,
	    stMqttMsgInfo.ip,
	    stMqttMsgInfo.diskSize,
	    stMqttMsgInfo.serverIp,
	    stMqttMsgInfo.port,
	    stMqttMsgInfo.devId,
	    stMqttMsgInfo.oldVer,
	    stMqttMsgInfo.curVer,
	    stMqttMsgInfo.tmpVer,
	    stMqttMsgInfo.appVer,
	    stMqttMsgInfo.oldFilename,
	    stMqttMsgInfo.curFilename,
	    stMqttMsgInfo.tmpFilename,
	    stMqttMsgInfo.appConfig
	);
}
void log_upload_prepare(const char*path)
{   
    system ("sync");
    htkj_system("cp %s  \"%s/sh_%s_%s.log\"",SHELL_LOG,path,stMqttMsgInfo.devId,currentTimeGet());
    htkj_system("echo '' > %s",SHELL_LOG);    
    if(access(UpanList_LOG,F_OK) == 0){
        htkj_system("cp %s  \"%s/uploadUpan_%s_%s.log\"",UpanList_LOG,path,stMqttMsgInfo.devId,currentTimeGet());
        htkj_system("echo '' > %s",UpanList_LOG);
    }
    if(access(A6List_LOG,F_OK) == 0){
        htkj_system("cp %s  \"%s/A6List_%s_%s.log\"",A6List_LOG,path,stMqttMsgInfo.devId,currentTimeGet());
        htkj_system("echo '' > %s",A6List_LOG);
    }
    logger_stop();
    htkj_system("mkdir -p %s;mv %s/log/*.log %s",path,DATA_STORE_BASE_PATH,path);    
    htkj_system("rm -f /upload/log/app");
    logger_reStart();
    logger_filename(stMqttMsgInfo.appLogFile,sizeof(stMqttMsgInfo.appLogFile));
    link(stMqttMsgInfo.appLogFile, "/upload/log/app"); 
}


INT32 htkj_system(char * format,...)
{
    CHAR cmd[2048] = {0};
    va_list aptr;
   
    va_start(aptr, format);
    vsprintf(&cmd[strlen(cmd)], format , aptr);
    va_end(aptr);

    return system(cmd);   
}

INT32 systemOut(const char *cmd, char *result,int size)   
{ 
    FILE *ptr = NULL; 
    CHAR *P = NULL;  
      
    if(cmd == NULL || result == NULL)
        return ERROR;
    if((ptr = popen(cmd, "r"))!=NULL)   
    {   
        fseek(ptr, 0, SEEK_SET);
        fgets(result, size, ptr);
        pclose(ptr);   
        P = result; 
        while(*P && !isspace(*P))
            P++;
	if(*P != '\0')
            *P = '\0';	
    }   
    else  
    {   
        printf("popen %s error\n", cmd);   
        return ERROR;
    }
    return OK;   
}

INT32 isValidKey(INT8 c){//a~z A~Z 0~9 _
    if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' )
	return 1;
    else
	return 0;
}
INT32 fileSize(const INT8* fname)
{
    struct stat statbuf;
    if(stat(fname,&statbuf)==0)
        return statbuf.st_size;
    return -1;
}
INT32 getLine(const INT8 *content,INT8 *line, INT32 size)
{
    INT32 pos = 0;

    while(pos < size){
        if(*content != '\r' && *content != '\n' && *content != '\0'){
	     line[pos++] = *content++;	
	}else{
	     return ++pos;
	}
    }
    return 0;
}
void clearFile(const INT8* fname)
{
    htkj_system("rm -fr %s",fname);
}
INT32 insertConfig(const INT8 *key,const INT8 *content,const INT8 *path)
{
    FILE* fp;
    INT32 newLineLen = strlen(content); 
    INT32 bFoundKey = false;
    INT8 line[LINE_CONTENT_MAX_LEN] = {0};
    INT32 size = 0;
    INT8 *fullContent = NULL;
    INT8 *tFContent = NULL;
    INT32 startPos = 0;
    INT32 lineSize = 0;
    INT32 pos = 0;
	
    if(path == NULL || strlen(path) < 10){
	return -1;
    }
    size = fileSize(path);
    if(size < 0){
        strcpy(line,content);
        line[strlen(line) - 1] = 0;
        htkj_system("echo %s > %s",line,path);
        return 0; 
    }	

    fullContent = (INT8*)malloc(size + LINE_CONTENT_MAX_LEN);    
    if(fullContent == NULL ){	
    	return -1;
    }
    tFContent = (INT8*)malloc(size + LINE_CONTENT_MAX_LEN);
    if(tFContent == NULL){
        free(fullContent);
        return -1;
    }
    memset(fullContent,0,size + LINE_CONTENT_MAX_LEN);
    memset(tFContent,0,size + LINE_CONTENT_MAX_LEN);
    fp = fopen(path, "r");
    if(fp == NULL)
    {
        Error("%s: R Opent file %s failed.\n", __FILE__, path);
	free(fullContent);
	free(tFContent);
        return -1;
    }
    fread(fullContent,1,size + LINE_CONTENT_MAX_LEN,fp);
    fclose(fp);
    memcpy(tFContent,fullContent,size);//data bakup
    while(pos < size){
	memset(line, 0, LINE_CONTENT_MAX_LEN);
	startPos = pos;
        pos += getLine(&fullContent[pos],line,size-pos);//read a li
	if(!isValidKey(line[0])){
            continue;
        }
	if(strncmp(line, key, strlen(key)) == 0){//find key
	    if(line[strlen(key)] != '='){
	    	continue;
    	    }
	    bFoundKey = true;
      	    //printf("%s:%s \n", __func__, content);
            lineSize = pos - startPos;
	    break;
	}
    }
    if(bFoundKey == true){	
	memcpy(&fullContent[startPos],content,newLineLen);
	memcpy(&fullContent[startPos + newLineLen],&tFContent[startPos + lineSize],size - startPos - lineSize);
	fullContent[size + newLineLen - lineSize] = 0;
    }else{
	strcpy(&fullContent[size],content);
    }
    size = strlen(fullContent);
    clearFile(path);
    
    fp = fopen(path, "w");
    if(fp == NULL)
    {
        Error("%s: W Opent file %s failed.\n", __FILE__, path);
	free(fullContent);
	free(tFContent);
        return -1;
    }
    fwrite(fullContent,1,size,fp);
    fclose(fp);   
    free(fullContent);
    free(tFContent);
    return 0;
}
INT32 setKeyValue(const INT8 *key,const INT8 *value)
{
    INT8  content[LINE_CONTENT_MAX_LEN] = {0};

    sprintf(content, "%s=%s\n", key, value);
    return insertConfig(key,content, stMqttMsgInfo.versionConfig);
}
INT8* getKey_real(const INT8* key,INT8* value,const INT8* path)
{
    FILE* fp;
    INT32 i = 0;
    INT32 lineContentLen = 0;
    INT32 position = 0;
    INT8 lineContent[LINE_CONTENT_MAX_LEN];
  	
    if(path == NULL || strlen(path) < 10)
	return value;
	
    if( 0 != access(path,F_OK) )
        return value;

    fp = fopen(path, "r");
    if(fp == NULL)
    {
        Error("%s: GR Opent file %s failed.\n", __FILE__, path);
        return value;
    }
    while(feof(fp) == 0)
    {
        memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
        fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);

        if(!isValidKey(lineContent[0])){
            continue;
        }
       
        //check key
        if(strncmp(lineContent, key, strlen(key)) == 0)
        {
            lineContentLen = strlen(lineContent);
	    if(lineContent[strlen(key)] != '=')
		continue;
            //find value
            position = strlen(key) + 1;
            if(position >= lineContentLen) 
		continue;
	//		bFoundKey = true;
            strncpy(value, &lineContent[position], lineContentLen - position);
            lineContentLen = strlen(value);
            for(i = 0; i < lineContentLen; i++)
            {
                if((value[i] == '\0') || (value[i] == '\r') || (value[i] == '\n'))
                {
                    value[i] = '\0';
                    break;
                }
            }  
        }
               
    }
    fclose(fp); 
    return value;    
}
INT8* getKey(const INT8* key,INT8* value,const INT8 * filename)
{
     return getKey_real(key,value, filename);
}
INT8* getKey_ver(const INT8* key,INT8* value)
{
    return getKey_real(key,value, stMqttMsgInfo.versionConfig);
}

INT32 setKeyValue_str(const INT8 * key,INT8 *value)
{
    return setKeyValue(key, value);
}
INT32 setKeyValue_int(const INT8* key,INT32 value)
{
    INT8 buf[64] = {0};
    
    sprintf(buf,"%d",value);
    return setKeyValue(key, buf);
}
INT32 rmKeyValue(const INT8 *key)
{
    INT8  content[LINE_CONTENT_MAX_LEN] = {0};

    sprintf(content, "%s=\n", key);
    return insertConfig(key,content, stMqttMsgInfo.versionConfig);
}
INT32 com_rmKeyValue(const INT8 *key,const INT8 *filename)
{
    INT8  content[LINE_CONTENT_MAX_LEN] = {0};

    sprintf(content, "%s=\n", key);
    return insertConfig(key,content, filename);
}
INT8* com_getKeyValue(const INT8* key,INT8* value,const INT8 * filename)
{
    return getKey(key, value, filename);
}
INT32 com_setKeyValue(const INT8* key,const INT8* value,const INT8 *filename)
{
    INT8  content[LINE_CONTENT_MAX_LEN] = {0};

    sprintf(content, "%s=%s\n", key, value);
    return insertConfig(key,content, filename);
}
INT32 get_clientID (CHAR *sn,int size,const CHAR* filename)
{
    char linuxVersion[128] = {0};
   
    if(sn == NULL)
        return ERROR;
      
    getKey("HWVersion",linuxVersion,filename);
    
    if(strcmp(linuxVersion , "V0") == 0){//qiantu
        systemOut ("cat /proc/cmdline |awk '{print $5}'", sn,size);
    }else if(strcmp(linuxVersion , "V1") == 0){//diange
        systemOut ("cat /proc/cmdline |awk '{print $6}'", sn,size);
    }
    
    return OK;
}
BOOL readConfig(const INT8* path)
{
    CHAR buf[LINE_CONTENT_MAX_LEN];
    CHAR filename[LINE_CONTENT_MAX_LEN];
        
    htkj_system("mkdir -p /upload/log");
    get_clientID(stMqttMsgInfo.devId,sizeof(stMqttMsgInfo.devId),path);//ÅœÃubootÂ²ÃÃÃœÃÃÂ¶ÃÃÂ¡
    sprintf(filename,"%s/app_%s",SYSTEM_LOG_PATH,stMqttMsgInfo.devId);
    logger_init(filename, LOG_DEFAULT_LEVEL,LOG_DEFAULT_MAX_SIZE);
    htkj_system("rm -f /upload/log/app");
        
    logger_filename(stMqttMsgInfo.appLogFile,sizeof(stMqttMsgInfo.appLogFile));
	link(stMqttMsgInfo.appLogFile, "/upload/log/app"); 
	
	if(path == NULL){
	    Error("%s not empty!\n",path);
	    return 0;
	}
	if(0 != access(path, F_OK | R_OK)){
	    INFO("%s need read permission!\n",path);
	    htkj_system("chmod 777 %s",path);
	}
	strcpy(stMqttMsgInfo.appConfig,path);
	getKey("air_server_ip",stMqttMsgInfo.serverIp,path);
	stMqttMsgInfo.port = atoi(getKey("air_server_port",buf,path));
    
        stMqttMsgInfo.regInterval = atoi(getKey("air_REG_interval",buf,path));
        stMqttMsgInfo.regTimeout = atoi(getKey("air_REG_timeout",buf,path));
	stMqttMsgInfo.HBInterval = atoi(getKey("air_HB_interval",buf,path));
        stMqttMsgInfo.HBTimeout = atoi(getKey("air_HB_timeout",buf,path));
	stMqttMsgInfo.loopLogInterval = atoi(getKey("LOOP_LOG_INTERVAL",buf,path))*60;
	stMqttMsgInfo.keepIdle = atoi(getKey("air_keepIdle",buf,path));
	stMqttMsgInfo.keepInterval = atoi(getKey("air_keepInterval",buf,path));
	stMqttMsgInfo.keepCount = atoi(getKey("air_keepCount",buf,path));
	stMqttMsgInfo.ftpChannelNum = atoi(getKey("ftp_Channel_num",buf,path));	
	
	//ÃÃ€ÃÃÃÃÅÃŸ
	getKey("versionFile",stMqttMsgInfo.versionConfig ,path);
	getKey("upload_path",stMqttMsgInfo.uploadLinkPath,path);
        getKey("transfer_path",stMqttMsgInfo.transferPath,path);
        strcpy(stMqttMsgInfo.baseUploadPath,UPLOAD_BASEPATH);


	getKey("upgrade_DIR",stMqttMsgInfo.upgradeDir,path);	
	stMqttMsgInfo.consoleLog = atoi(getKey("console_log",buf,path));	
	//stMqttMsgInfo.airLogMaxTimeout = atoi(getKey("AIR_LOG_MAX_Interval",buf,path));
	//stMqttMsgInfo.conFLogInterval = atoi(getKey("air_con_fail_log_interval",buf,path));
	stMqttMsgInfo.ftpNoTimeout = atoi(getKey("ftp_NO_SEND_TIMEOUT",buf,path));  
	get_appVer (stMqttMsgInfo.appVer);//Â±Ã ÃÃ«ÃÂ±ÅœÂ«Â²ÃÂ»Ã±ÃÂ¡
	get_diskSize(stMqttMsgInfo.diskSize);       
	
        
        stMqttMsgInfo.block_max_size = atoi(getKey("block_max_size",buf,path));
        stMqttMsgInfo.route_min_time = atoi(getKey("route_min_time",buf,path)); 
                
    	stMqttMsgInfo.isUsbCollect = atoi(getKey("dataCollect_usb",buf,path));
        getKey("sysConfFile",filename,path);
	if(strlen(filename) < 5){
	    Error("sysConfFile [%s] not empty!\n",filename);
	    return 0;
        }
	if(0 != access(filename, F_OK | R_OK | W_OK)){
	    INFO("%s need read-write permission!\n",filename);
	    htkj_system("chmod 777 %s",filename);
	}
	
        getKey("air_server_ip",stMqttMsgInfo.serverIp,filename);
	stMqttMsgInfo.port = atoi(getKey("air_server_port",buf,filename));
        getKey("air_local_ip",stMqttMsgInfo.ip,filename);
        get_localMAC (buf, stMqttMsgInfo.netName);
	if(strlen(stMqttMsgInfo.versionConfig) < 5){
		Error("versionFile [%s] not empty!\n",stMqttMsgInfo.versionConfig);
		return 0;
	}
	if(0 != access(stMqttMsgInfo.versionConfig, F_OK | R_OK | W_OK)){
		INFO("%s need read-write permission!\n",stMqttMsgInfo.versionConfig);
		htkj_system("chmod 777 %s",stMqttMsgInfo.versionConfig);
	}
	//Â°ÃŠÂ±ÅžÂºÃ
	//CHAR firmVer[ARGV_MAX_LEN];
	getKey_ver("app_old_version",stMqttMsgInfo.oldVer);
	getKey_ver("app_cur_version",stMqttMsgInfo.curVer);
	getKey_ver("app_tmp_version",stMqttMsgInfo.tmpVer);
	//ÃÃœÅÂ¶Â°ÃŒÃÃ»Â³Ã
	getKey_ver("app_old_filename",stMqttMsgInfo.oldFilename); 
	getKey_ver("app_cur_filename",stMqttMsgInfo.curFilename);
	getKey_ver("app_tmp_filename",stMqttMsgInfo.tmpFilename);
	
	//ÅÃ¬Â²Ã©Â²ÃÃÃœ
	
	return 1;
} 

UINT8 isEmptyDir(const INT8* path)
{
    DIR *dir = opendir(path);
    struct dirent *ent;
    if (dir == NULL) {  
        Error("isEmptyDir open DIR %s error",path);
        return 0;
    }  
    while (1){  
        ent = readdir (dir);
        if (ent <= 0) {  
            break;
        }  
        if ((strcmp(".", ent->d_name) == 0) || (strcmp("..", ent->d_name) == 0)) {  
            continue;
        }  

        if ((ent->d_type == 4) || (ent->d_type == 8)) {  
            closedir(dir);
            return 0;
        }  
    }  
    closedir(dir);
    return 1;
}
void delEmptyDir(const INT8* path)
{
    DIR *dir;
    struct dirent *ptr;
    char base[1000];  

    if ((dir=opendir(path)) == NULL) {
        Error("error %s",path);
        return ;
    }
    while ((ptr=readdir(dir)) != NULL){
        if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0) {   ///current dir OR parrent dir
            continue;
        }else if(ptr->d_type == 8 ){///file
	    continue;
        }else if(ptr->d_type == 4){    ///dir	    
            memset(base,'\0',sizeof(base));
	    sprintf(base,"%s/%s",path,ptr->d_name);
	    if(isEmptyDir(base)){
		rmdir(base);
	    }else{
		delEmptyDir(base);
	    }
        }
    }
    closedir(dir);
    return;
}
int file_lastTime(const char* basePath)
{
    CHAR cmd[LINE_CONTENT_MAX_LEN] = {0};
    CHAR _6aT[0x40] = {0}; 
    
    if(access(basePath,F_OK) != 0)
        return 0;
        
    sprintf(cmd,"stat %s/*VIDEO* | grep Modify| tail -n 1 | cut -d' ' -f2- | awk -F'.' '{printf $1}'",basePath);

    systemOut(cmd,_6aT,sizeof(_6aT));
    if(strlen(_6aT) > 0)
        return strTime2Int(_6aT);
    else 
        return 0;
}
UINT64 getPathData_realSize(const char* path)//kB
{
    CHAR size[0x40] = {0};  
    CHAR cmd[1024] = {0};    

    sprintf(cmd,"find %s -type f|xargs -i ls -l '{}' |awk '{print $5}' |awk 'BEGIN {SUM=0} {SUM+=$1} END {printf(\"%%d\",SUM/1024)}'" , path);  
    systemOut ( cmd , size, sizeof(size));
   
    return atoi (size);
}
UINT64 getPathDataSize(const char* path)
{
    CHAR size[0x40] = {0};  
    CHAR cmd[1024] = {0};

    if(access(path,F_OK) != 0)
        return 0;
    sprintf(cmd,"du -sk %s | awk '{print $1}'" , path);  
    systemOut ( cmd , size, sizeof(size));

    return (UINT64)atoll (size);
}

INT32 getSpeed()
{
    char cmd[0x400] = {0};
    char speed[40] = {0};
    
    if(strlen(stMqttMsgInfo.netName) <= 0){
        return 0;
    }
    sprintf (cmd,"sar -n DEV 1 1 | grep %s | grep -v Average | awk '{print $6}'", stMqttMsgInfo.netName); 	
    systemOut (cmd,speed ,sizeof(speed));

    return atoi(speed);
}

INT32 getPathFilesCount(const char* path)
{
    CHAR cmd[0x400] = {0};
    CHAR size[0x40] = {0};

    sprintf (cmd, "ls -lR %s | grep -v \"license.txt\" | grep ^- | wc -l", path); 
    systemOut (cmd,size, sizeof(size));

    return atoi (size);
}
UINT8 getUSBDisk(void)
{
    CHAR count[0x40] = {0};

    systemOut ("fdisk -l  | grep /dev/sd | grep -v 'sda\\|Disk' |tail -n 1 | wc -l",count, sizeof(count));//"/tmp/.usbdiskisExist.tmp");
    return atoi(count); 
}
UINT32 getUSBDiskPlugTimes(UINT8 flg)//0:current 1:reg 2:power on or upload
{
    FILE *fp;
    UINT32 count = 0;
    UINT32 regCount = 0;
    UINT32 countPower = 0;
    char buf[1024] = {0};
    char *line = buf;
    size_t len = 0;

    fp = fopen(stMqttMsgInfo.appLogFile, "r");
    if(fp == NULL){
           Error("%s: R Open file %s failed.\n", __FILE__, stMqttMsgInfo.appLogFile);
           return 0;
    }
    while (getline(&line, &len, fp) != -1) {
	if(strstr(line,"detect usb plug") != NULL){
	    count++;
            countPower++;
	} else if(strstr(line,"system POWER UP") != NULL || strstr(line,"system POWER OFF") != NULL){
	    regCount += count;
	    count = 0;
            countPower = 0;
	}else if(strstr(line,"register server OK") != NULL){
            regCount = 0;
	    count = 0;
        }
	memset(buf,0,sizeof(buf));
    }    
    fclose(fp); 
    regCount += count;
    if(flg == 1)
	return regCount;
    else if(flg == 2)
        return countPower;
    else
    	return count;    
}

void _sort(int index[],int size)
{
    int i,j;
    int tmp;

    for(i = 0; i < size;i++){
	for(j = i; j < size;j++){
            if(index[i] > index[j]){
		tmp = index[i];
 		index[i] = index[j];
                index[j] = tmp;
            }
	}
    }
}
void setPOE(int flg)
{
    if(flg != 0){
        htkj_system("%s on",APP_POE);
        htkj_system("%s on",APP_POE);
        htkj_system("%s on",APP_POE);
        stMqttMsgInfo.poeIsON = 1;
        INFO("turn POE ON");
        htkj_system("rm -f /tmp/.poeflg");
    }else{
        htkj_system("%s off",APP_POE);
        htkj_system("%s off",APP_POE);
        stMqttMsgInfo.poeIsON = 0;
        INFO("turn POE OFF");
        htkj_system("touch /tmp/.poeflg");
    }
}
void init_system(void)
{
    CHAR filename[512] = {0};
    CHAR data[LINE_CONTENT_MAX_LEN]={0};   
   
    htkj_system("mkdir -p /upload/data");
    htkj_system("mkdir -p /upload/video");
    htkj_system("mkdir -p /upload/dataLink");
    htkj_system("mkdir -p /upload/Upan");
    htkj_system("mkdir -p /upload/log");
    htkj_system("mkdir -p /AIR_FLASH/ver");
    if(access("/tmp/hostProcess_check",F_OK) != 0){    
        INFO("@@@@@@@@@@@@@@@@@@@@system POWER UP now");
        htkj_system("touch /tmp/hostProcess_check"); 
        if(access("/upload/log/.profile",F_OK) == 0){
            htkj_system("cat /upload/log/.profile >> /upload/log/.onofftimes"); 
        } 
        delEmptyDir(stMqttMsgInfo.uploadLinkPath);  
        delEmptyDir(stMqttMsgInfo.uploadLinkPath);  
        delEmptyDir(stMqttMsgInfo.uploadLinkPath);
        delEmptyDir(stMqttMsgInfo.uploadLinkPath);
    }
    INFO("APP started local time:[%d;%s]",currentTimeGet_int(),currentTimeGet());    
    
    htkj_system("rm -fr %s/6A-VIDEO* > /dev/null 2>&1",stMqttMsgInfo.baseUploadPath);
    sprintf(filename,"%s/%s",stMqttMsgInfo.baseUploadPath,VIDEO_CONF);  
    stMqttMsgInfo.oNTimeDuration = atoi(com_getKeyValue(lastPowerTimeLen ,data, filename));     
    stMqttMsgInfo.powerONTime = currentTimeGet_int();
    stMqttMsgInfo.uploadStartSize = getPathDataSize(stMqttMsgInfo.baseUploadPath);//KB
    stMqttMsgInfo.A6StartSize = getPathDataSize(A6_PATH);//KB    
    stMqttMsgInfo.transferStartSize = getPathDataSize(stMqttMsgInfo.transferPath);//KB 
    stMqttMsgInfo.UplugTimes = getUSBDiskPlugTimes(1);   
    pthread_rwlock_init(&stMqttMsgInfo.rwlock, NULL); 
    pthread_rwlock_init(&stMqttMsgInfo.profile_lock, NULL);     
    pthread_mutex_init(&stMqttMsgInfo.block_mutex, NULL);  
    setPOE(1);  
}

int sort_dir(const char* basePath,const char* pathName ,int index[])
{
    DIR *dir;
    struct dirent *ptr;  
    int i = 0;
	
    if ((dir=opendir(basePath)) == NULL){
        return 0;
    }

    while ((ptr=readdir(dir)) != NULL)
    {
        if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0){    ///current dir OR parrent dir
            continue;        
        }else if(ptr->d_type == 4){    ///dir
	    if(strncmp(ptr->d_name,pathName,strlen(pathName)) == 0){
		index[i++] = atoi(&ptr->d_name[strlen(pathName)]);
	    }
        }
    }
    closedir(dir);
    _sort(index,i);
    return i;
}
int divide_group(void)
{
    int groupIdx[BLOCK_MAX_COUNT] = {0};
    int size;
    int nid = 0;

    size = sort_dir(stMqttMsgInfo.baseUploadPath,VIDEO_BLOCK,groupIdx);
    if(size <= 0){//no block
        return -1;
    }
    size = sort_dir(stMqttMsgInfo.baseUploadPath,VIDEO_GROUP,groupIdx);
    if(size > 0){
        nid = groupIdx[size - 1] + 1;
        size++;
    }

    htkj_system("mkdir -p %s/%s%d",stMqttMsgInfo.baseUploadPath,VIDEO_GROUP,nid);
    htkj_system("mv -f %s/%s* %s/%s%d/",stMqttMsgInfo.baseUploadPath,VIDEO_BLOCK,stMqttMsgInfo.baseUploadPath,VIDEO_GROUP,nid);
    htkj_system("cat %s > %s/%s%d/%s",UPLOADBlock_SIZEF ,stMqttMsgInfo.baseUploadPath,VIDEO_GROUP,nid ,VIDEO_CONF);
    htkj_system("rm -f %s" , UPLOADBlock_SIZEF);

    INFO("create new group %d",size);
    return nid;//size
}
/*
void rm_repeatFiles(const char *basePath,const char *path,int nid,int oid  )
{
    DIR *dir;
    struct dirent *ptr;
    char npath[1024];
    char relatPath[1024];

  
    if(path != NULL){
    	sprintf(npath,"%s/%s%d/%s",basePath,VIDEO_BLOCK,nid,path);
    }else{
        sprintf(npath,"%s/%s%d",basePath,VIDEO_BLOCK,nid);
    }
   
    if ((dir=opendir(npath)) == NULL) {
       return;
    }

    while ((ptr=readdir(dir)) != NULL){
        if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0) {   ///current dir OR parrent dir
            continue;
        }else if(ptr->d_type == 8){    ///file
	    if(strcmp(ptr->d_name,VIDEO_CONF) == 0){
                continue;
            }
            char opath[1024] = {0};
            if(path != NULL){
    	        sprintf(opath,"%s/%s%d/%s/%s",basePath,VIDEO_BLOCK,oid,path,ptr->d_name);
            }else{
                sprintf(opath,"%s/%s%d/%s",basePath,VIDEO_BLOCK,oid,ptr->d_name);
            }
	    if(access(opath,F_OK) == 0){
                htkj_system("rm -f %s",opath);//rm file
            }
        }else if(ptr->d_type == 4){    ///dir  
            if(path != NULL){
		sprintf(relatPath,"%s/%s",path,ptr->d_name);
 	    }else{
                sprintf(relatPath,"%s",ptr->d_name);
            }      
          //  rm_repeatFiles(basePath,relatPath,nid,oid);
        }
    }
    closedir(dir);
    return;
}*/

int divide_block(void)
{
    int blockIdx[BLOCK_MAX_COUNT] = {0};
    int size;
    int nid = 0;
    char srcPath[0x400] = {0};
    char dstPath[0x400] = {0};
    CHAR key[32] = {0};
    CHAR value[32] = {0};   
    int dataSize = 0;

    size = sort_dir(stMqttMsgInfo.baseUploadPath,VIDEO_BLOCK,blockIdx);
    if(size > 0){
        nid = blockIdx[size - 1];// + 1;
    } 
    
    sprintf(srcPath,"%s",UNIFY_BASE_PATH);//stMqttMsgInfo.uploadLinkPath);//src path
    pthread_rwlock_wrlock(&stMqttMsgInfo.rwlock);//请求写锁
    dataSize = stMqttMsgInfo.videoSize;
    
    if(dataSize/1024 < VIDEO_BLOCK_MIN_SIZE){ //<10MB
        pthread_rwlock_unlock(&stMqttMsgInfo.rwlock);//解锁
        Error("divide_block data < 10MB %d",dataSize/1024);
        return size;
    }
    if(size > 0){      
        nid++;
        size++;       
    }
    
    sprintf(dstPath,"%s/%s%d",stMqttMsgInfo.baseUploadPath,VIDEO_BLOCK,nid);
    htkj_system("mkdir -p %s",dstPath);      
    htkj_system("mv -f %s/* %s/ ",srcPath,dstPath);    
    
    sprintf(key,"block%dSize",nid);   
    sprintf(value,"%d",dataSize);
    stMqttMsgInfo.videoSize = 0;
    com_setKeyValue(key,value,UPLOADBlock_SIZEF);
    pthread_rwlock_unlock(&stMqttMsgInfo.rwlock);//解锁
    INFO("create new block %d",size);
    return nid;//size     
}

void dirBySuffix_link(const INT8* sDir,const INT8* dDir,const INT8* suffix)
{
    DIR *sdir = NULL;    
    struct dirent *ent;
    CHAR sPath[512] = {0}; 
    CHAR dPath[512] = {0};  

    if(access(dDir,F_OK) != 0){
        htkj_system("mkdir -p %s" , dDir);
    }
    sdir = opendir(sDir);
    if (sdir == NULL) {  
        Error("open src DIR %s error",sDir);
        return;
    }   
    while (1){        
        INT32 index = 0;
        
        ent = readdir (sdir);
        if (ent <= 0) {  
            break;
        }  
        if ((strcmp(".", ent->d_name) == 0) || (strcmp("..", ent->d_name) == 0)) {  
            continue;
        }  
        if(ent->d_name[0] == '.')
            continue;
        sprintf(sPath ,"%s/%s" , sDir,ent->d_name);
        sprintf(dPath ,"%s/%s" , dDir,ent->d_name);
        if ((ent->d_type == DT_REG) || (ent->d_type == DT_LNK)) { //8 10
            if(suffix){//*.tmp ".tmp"
                index = strlen(ent->d_name) - strlen(suffix);
                if(index < 0)
                    continue;
                if(strcmp(&ent->d_name[index],suffix) != 0)
                    continue;
                dPath[strlen(dPath) - strlen(suffix)] = '\0';
            }
            if(0 == link(sPath,dPath)){
                clearFile(sPath);
            }                
        }else if(ent->d_type == DT_DIR){
            dirBySuffix_link(sPath ,dPath,suffix);
        }
    }  
    closedir(sdir);    
    return;
}
void htkj_log(const char *func_name, int line, const char *fmt, ...)
{   
    if(!stMqttMsgInfo.consoleLog)
        return;
    CHAR buffer[4096] = {0};
    va_list aptr; 
    
    sprintf(buffer,"[%s]---",currentTimeGet0());
    if(func_name != NULL)
        sprintf(&buffer[strlen(buffer)],"%s",func_name);
    if(line > 0)
        sprintf(&buffer[strlen(buffer)],":%d",line);  
    va_start(aptr, fmt);
    vsprintf(&buffer[strlen(buffer)], fmt , aptr);
    va_end(aptr);
    printf("%s\n",buffer);   
}
/******************************* ÃÅœÃÃÅÃŸÅÃ¡ÃÃž **********************************/
